package com.example.demo.util.httpclient;

import org.apache.commons.codec.binary.Hex;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author liujj
 **/
public class OpenApiClient {
    private static final String version = "2.0";
    private static final String default_app_key = "ZUDGHH";
    private static final String default_secretkey = "H9D0ggre7EP0TYLpL1iE";

    public static <T> T get(final String url, RestTemplate restTemplate, ParameterizedTypeReference<T> typeReference) {
        HttpEntity<MultiValueMap<String, String>> requestEntity = getMultiValueMapHttpEntity(null);
        return restTemplate.exchange(url, HttpMethod.GET, requestEntity, typeReference).getBody();
    }
    public static <T> T get(URI uri, RestTemplate restTemplate, ParameterizedTypeReference<T> typeReference) {
        HttpEntity<MultiValueMap<String, String>> requestEntity = getMultiValueMapHttpEntity(null);
        return restTemplate.exchange(uri, HttpMethod.GET, requestEntity, typeReference).getBody();
    }

    public String post(final String url, Map<String, Object> params, RestTemplate restTemplate) {
        HttpEntity<MultiValueMap<String, String>> requestEntity = getMultiValueMapHttpEntity(params);
        System.out.println(restTemplate);
        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class).getBody();
    }

    private static HttpEntity<MultiValueMap<String, String>> getMultiValueMapHttpEntity(Map<String, Object> params) {
        HttpHeaders headers = getHttpHeaders(params);
        MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
        if (null != params && params.size() > 0) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                multiValueMap.add(entry.getKey(), entry.getValue().toString());
            }
        }
        return new HttpEntity<>(multiValueMap, headers);
    }

    private String getSign(Map<String, Object> applicationParam, String timestamp) {
        HashMap<String, Object> coll = new HashMap<>();
        coll.put("app_key", default_app_key);
        coll.put("timestamp", timestamp);
        coll.put("v", version);
        if (applicationParam != null) {
            coll.putAll(applicationParam);
        }
        String appSecret = default_secretkey;
        List<Map.Entry<String, Object>> params = new ArrayList<>(coll.entrySet());
        params.sort(Map.Entry.comparingByKey());
        StringBuilder sb = new StringBuilder();
        sb.append(appSecret);
        for (Map.Entry<String, Object> item : params) {
            String key = item.getKey();
            Object value = item.getValue();
            if (value == null) {
            } else if (value instanceof Object[]) {
                Object[] values = (Object[]) value;
                String str = "[";
                for (int i = 0; i < values.length; i++) {
                    if (i > 0)
                        str += ",";
                    str += values[i];
                }
                str += "]";
                sb.append(key).append(str);
            } else {
                sb.append(key).append(value);
            }
        }
        return md5Sum(sb.append(appSecret).toString());

    }

    private String md5Sum(String plain) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
            String md5 = new String(Hex.encodeHex(md.digest(plain.getBytes(StandardCharsets.UTF_8))));
            return md5.toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    private static HttpHeaders getHttpHeaders(Map<String, Object> params) {
        String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Access-Token", new OpenApiClient().getSign(params, timestamp));
        headers.add("Access-Version", version);
        headers.add("Access-Key", default_app_key);
        headers.add("Access-Timestamp", timestamp);
        return headers;
    }

    public static void main(String[] args) {
        HttpEntity<MultiValueMap<String, String>> requestEntity = getMultiValueMapHttpEntity(null);
        String body = new RestTemplate().exchange("http://glapi.lenovo.com/router/v2/address/v3/getAll?id=978880162@qq.com", HttpMethod.GET, requestEntity, String.class).getBody();
        System.out.printf(body);
    }

}
